using Basis;
using System;
using UnityEngine;

namespace NL.Advanced
{


    public enum TargeterMode
    {
        Size = 0,
        Direction = 1,
        Single = 11,
    }

    public class RangeSelecter : MonoBehaviour, IISkillRangeSelecter
    {

        float IISkillRangeSelecter.Range => Range;

        float IISkillRangeSelecter.Size => Size;

        GameObject IISkillRangeSelecter.Ranger => Ranger;

        GameObject IISkillRangeSelecter.Selecter => Selecter;

        Vector3 IISkillRangeSelecter.SelectorDir
        {
            get
            {
                if (Selecter == null) return transform.forward;
                else
                {
                    Vector3 _dir = (Selecter.transform.position - transform.position);
                    _dir.y = 0;
                    return _dir.normalized;

                }
            }
        }

        bool IISkillRangeSelecter.SelecterInRange
        {
            get
            {
                if (Selecter == null) return true;

                return Vector3.Distance(Selecter.transform.position, transform.position) < Range;
            }
        }

        private bool _IsForbidden;
        bool IISkillRangeSelecter.IsForbidden
        {
            get
            {
                return _IsForbidden;
            }
        }

        Action<IISkillRangeSelecter> _OnTargeted;

        IISkillRangeSelecter IISkillRangeSelecter.Select()
        {
            Invoke("_DoSelect", 0); return this;
        }

        IISkillRangeSelecter IISkillRangeSelecter.WaitSelect(Action<IISkillRangeSelecter> _on)
        {
            _OnTargeted = _on; return this;
        }

        //IISkillRangeSelecter IISkillRangeSelecter.Show(Vector3 pos)=>Show(pos);

        //IISkillRangeSelecter IISkillRangeSelecter.Hide()=>Hide();

        //IISkillRangeSelecter IISkillRangeSelecter.Reset()=>Reset();


        [Header("目标范围 Range<0 表示全屏 ,Hub显示")]
        public float Range = 3;
        public GameObject Ranger;



        [Header("目标选择器类型:原型尺寸(size有效);方向指引,单体")]
        public TargeterMode Mode = TargeterMode.Size;
        public GameObject Selecter;
        public float SelectorOffSetY = 1f;
        public float Size = 1;

        [Header("出生点")] public Transform BornPoint;


        public float ShowingForNoRange = 0.2f;


        public Vector3 SelectorDir
        {
            get
            {
                Vector3 _dir = Selecter == null ? transform.forward : (Selecter.transform.position - transform.position).normalized;
                _dir.y = 0;
                return _dir.normalized;
            }
        }

        public bool ResetPosEach = true;


        //CombaterRanger _Ranger;
        Vector3 _OldPos;
        Quaternion _OldDir;



        protected virtual void Awake()
        {
            _OldPos = transform.localPosition;
            _OldDir = transform.localRotation;
            // _Ranger = GetComponentInChildren<CombaterRanger>();

            RandSelecter();
        }

        protected virtual void OnEnable()
        {

        }

        protected virtual void _DoSelect()
        {

            if (ResetPosEach)
            {
                transform.localPosition = _OldPos;
                transform.localRotation = _OldDir;
            }
            gameObject.SetActive(true);

            if (Range > 0)
            {

            }
            else
            {
                _SelectDone();
            }

        }

        protected virtual void _SelectDone()
        {
            _OnTargeted?.Invoke(this);

            gameObject.SetActive(false);
        }

        public RangeSelecter Show()
        {

            if (Ranger != null)
            {
                if (Range == 0 || Range >= 999)
                    Ranger.GetComponent<IRange>()?.Reset(0);
                else
                    Ranger.GetComponent<IRange>()?.Reset(Range);
            }


            return this;

        }

        public IISkillRangeSelecter ShowRange()
        {
            if (Ranger != null)
            {
                Ranger.GetComponent<IRange>()?.Reset(Range > 0 ? Range : 9999);
            }
            Selecter.SetActive(false);
            return this;
        }

        public IISkillRangeSelecter Show(Vector3 pos)
        {

            if (Ranger != null)
            {
                if (Range == 0 || Range >= 999)
                    Ranger.GetComponent<IRange>()?.Reset(0);
                else
                    Ranger.GetComponent<IRange>()?.Reset(Range);
            }
            SelectPos(pos);

            return this;

        }

        public IISkillRangeSelecter SetSelectorPosition(Vector3 pos)
        {
            if (Selecter != null)
            {
                Selecter.transform.position = pos + Vector3.up * SelectorOffSetY;

                if (Mode == TargeterMode.Direction)
                {
                    Selecter.transform.forward = SelectorDir;
                }
            }
            return this;
        }

        public RangeSelecter SelectPos(Vector3 pos)
        {

            if (Selecter != null)
            {
                Selecter.transform.position = pos + Vector3.up * SelectorOffSetY;
                if (!Selecter.activeInHierarchy)
                    Selecter.SetActive(true);

                if (Mode == TargeterMode.Direction)
                {
                    Selecter.transform.forward = SelectorDir;
                }

                Selecter.GetComponentInChildren<IRange>()?.Reset(Size);

                //var combateRange = Selecter.GetComponent<CombaterRanger>();
                //if (combateRange != null)
                //{
                //    //指向性技能
                //}
                //else
                {
                    //定点技能
                    if (((IISkillRangeSelecter)this).SelecterInRange && GPS.IsOnRoad(Selecter.transform.position))
                        _IsForbidden = false;
                    else
                    {
                        _IsForbidden = true;
                    }
                }
            }
            return this;
        }

        public IISkillRangeSelecter Hide()
        {
            if (Selecter != null) Selecter.SetActive(false);
            if (Ranger != null) Ranger.SetActive(false);
            return this;
        }

        public bool CrossRoad = false;

        public IISkillRangeSelecter RandSelecter(bool _cossroad = false, string angleConfig = null)
        {
            if (Selecter != null)
            {

                Vector3 poa = Vector3.zero;
                var findPos = false;
                if (!string.IsNullOrEmpty(angleConfig))
                {
                    //角度配置为序号，序号对应关系如下
                    /*
                     *    6(135°) 7(90°) 8(45°)
                     *    5(180°) X 1(0°)
                     *    4(225°) 3(270°) 2(315°)
                     */
                    var indexes = angleConfig.Split(';');
                    foreach (var index in indexes)
                    {
                        var angle = (int.Parse(index) - 1) * (360f / 8);
                        var dir = Quaternion.AngleAxis(angle, Vector3.up);
                        var targetPosition = transform.position + dir * Vector3.right;
                        if (GPS.IsOnRoad(targetPosition))
                        {
                            findPos = true;
                            poa = targetPosition;
                            break;
                        }
                    }
                }

                if (findPos == false)
                {
                    poa = Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), Vector3.up) *
                                  Vector3.forward;
                    poa = poa * (UnityEngine.Random.Range(0f, 1f) * (Range * 0.8f) + 1);

                    poa = transform.position + poa;
                    if (_cossroad)
                    {
                        poa = poa.GetGPSPosition();
                        Vector3 other = 0.4f * transform.position + 0.6f * poa;
                        other = other.GetGPSPosition();

                        poa = other;
                    }
                }
                Selecter.transform.position = poa;
            }

            return this;
        }

        public void RandomBirthPoint(bool forceRoad = false)
        {
            if (Selecter != null)
            {
                Vector3 poa = Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), Vector3.up) *
                              Vector3.forward;
                poa = poa * UnityEngine.Random.Range(0f, 1f) * Size;

                poa = Selecter.transform.position + poa;
                if (forceRoad)
                {
                    poa = poa.GetGPSPosition();
                }
                BornPoint.position = poa;
            }
            else
            {
            }
        }
    }
}


